package dispatch;

import java.util.Observable;

public class Clock extends Observable {

	/**
	 * Variable registering the hours of this Clock
	 */
	private int hours = 0;

	/**
	 * Variable registering the hours of this Clock
	 */
	private int minutes = 0;

	/**
	 * Variable registering the previous total minutes of this Clock
	 */
	private int previousTotalMinutes = 0;

	/**
	 * Constructor for creating a Clock, with the given hours and minutes
	 * 
	 * @param hours
	 *            The hours you want to set on this clock
	 * 
	 * @param minutes
	 *            The minutes you want to set on this clock
	 * 
	 * @post A clock is initialized with the given hours and minutes
	 */
	public Clock(int hours, int minutes) {
		setHours(hours);
		setMinutes(minutes);
	}

	/**
	 * Method for advancing the time of this clock in minutes
	 * 
	 * @param minutes
	 *            The amount of minutes you want to advance the time
	 * 
	 * @post This clock it's minutes and hours are updated
	 * 
	 * @post The observers are notified, for moving units ( example )
	 */
	public void advanceTime(int minutes) {
		previousTotalMinutes = this.getTotalMinutes();
		this.minutes += minutes;
		this.hours += Math.floor(this.minutes / 60);
		this.minutes = this.minutes % 60;
		setChanged(); // set changed flag
		notifyObservers(this.hours); // do notification
		notifyObservers(this.minutes); // do notification
		notifyObservers(this.previousTotalMinutes); // do notification
	}

	/**
	 * Method for comparing this Clock with the given Clock
	 * 
	 * @param o
	 *            The clock you want to compare this Clock with
	 * 
	 * @return -1 if this clock is earlier than the given clock 0 if both Clocks
	 *         hours and minutes are equal. 1 if the given clock is earlier than
	 *         this clock
	 */
	public int compareTo(Clock o) {
		if (hours < o.getHours())
			return -1;
		else if (hours > o.getHours())
			return 1;
		else if (hours == o.getHours()) {
			if (minutes < o.getMinutes())
				return -1;
			else if (minutes > o.getMinutes())
				return 1;
			else
				return 0;
		}
		return 0;
	}

	/**
	 * Getter for getting the hours of this Clock
	 * 
	 * @return The hours of this clock
	 */
	public int getHours() {
		return hours;
	}

	/**
	 * Getter for getting the minutes of this Clock
	 * 
	 * @return The minutes of this clock
	 */
	public int getMinutes() {
		return minutes;
	}

	/**
	 * Method for calculating the different in minutes between this Clock and
	 * it's previous settings ( hours and minutes)
	 * 
	 * @return The time difference in minutes of this clock and it's previous
	 *         settings
	 */
	public int getTimeDif() {
		return getTotalMinutes() - previousTotalMinutes;
	}

	/**
	 * Getter for getting the totalminutes of this Clock
	 * 
	 * @return The totalminutes of this clock
	 */
	public int getTotalMinutes() {
		return minutes + (hours * 60);
	}

	/**
	 * Method for setting the hours of this Clock
	 * 
	 * @param minutes
	 *            The amount of hours on the clock
	 * 
	 * @post amount of hours on this clock is changed to the given hours if
	 *       hours<0 : hours is set to 0
	 */
	private void setHours(int hours) {
		if (hours < 0)
			this.hours = 0;
		else
			this.hours = hours;

	}

	/**
	 * Method for setting the minutes of this Clock
	 * 
	 * @param minutes
	 *            The amount of minutes on the clock
	 * 
	 * @post amount of minutes on this clock is changed to the given minutes if
	 *       minutes<0 : minutes is set to 0 if minutes>59: minutes is set to 59
	 */
	private void setMinutes(int minutes) {
		if (minutes < 0)
			this.minutes = 0;
		else if (minutes > 59)
			this.minutes = 59;
		else
			this.minutes = minutes;

	}

	/**
	 * toString method for this clock
	 * 
	 * @return the string representation of this Clock
	 */
	public String toString() {
		return hours + ":" + minutes;
	}

}
